package com.hyfrogx.modules.app.controller.zoom;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hyfrogx.common.exception.MyException;
import com.hyfrogx.common.log.LogEnum;
import com.hyfrogx.common.log.LogUtils;
import com.hyfrogx.common.param.PayType;
import com.hyfrogx.common.utils.DateUtils;
import com.hyfrogx.common.utils.QueryExt;
import com.hyfrogx.common.utils.R;
import com.hyfrogx.common.utils.RedisUtils;
import com.hyfrogx.common.validator.ValidatorUtils;
import com.hyfrogx.modules.app.annotation.Login;
import com.hyfrogx.modules.app.entity.OutMeetVo;
import com.hyfrogx.modules.app.entity.User;
import com.hyfrogx.modules.app.service.UserService;
import com.hyfrogx.modules.app.utils.FrogConstant;
import com.hyfrogx.modules.app.utils.StringUtils;
import com.hyfrogx.modules.manage.entity.payrecord.HyPayRecord;
import com.hyfrogx.modules.manage.service.HyPayRecordService;
import com.hyfrogx.modules.operation.entity.HyAppPushEntity;
import com.hyfrogx.modules.operation.service.umeng.UmengService;
import com.hyfrogx.modules.zoom.entity.*;
import com.hyfrogx.modules.zoom.form.OpenMeetForm;
import com.hyfrogx.modules.zoom.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author ：Li9527
 * @date ：Created in 2019-04-01 16:38
 * @description：客户端会议业务控制类
 * @modified By：
 * @version: 1.0
 */
@RestController
@RequestMapping("/api/zoom")
@Api(value = "客户端会议管理controller", tags = "客户端--会议业务(主开会)")
public class ApiZoomController {
    @Autowired
    HyZoomMeetingService meetingService;

    @Autowired
    HyZoomHistoryService historyService;

    @Autowired
    UserService frogUserService;

    @Autowired
    HyZoomUserService zoomUserService;

    @Autowired
    HyZoomVipUserService zoomVipUserService;

    @Autowired
    UmengService umengService;

    @Autowired
    RedisUtils redisUtils;

    Logger UMENG_LOG = LogUtils.Logger(LogEnum.UMENG_LOGS);

    @Autowired
    private HyLoginInfoService infoService;

    @Autowired
    HyZoomFeedbackService zoomFeedbackService;

    @Autowired
    MeetPriceService meetPriceService;

    @Autowired
    MeetJoinPriceService meetJoinPriceService;

    @Autowired
    HyZotConfigService hyZotConfigService;

    @Autowired
    HyPowerUserService powerUserService;

    @Autowired
    UserService userService;

    @Autowired
    HyPayRecordService payRecordService;

    /**
     * 通过主键id获取会议室
     *
     * @param id 会议室主键id
     * @throws MyException
     */
//    @Login
    @PostMapping("getMeetById")
    @ApiOperation("通过主键id获取会议室")
    public R getMeetById(@RequestParam(value = "id", required = true) Integer id) {
        try {
            HyZoomMeeting zoomMeeting = meetingService.getById(id);
            if (zoomMeeting != null) {
                return R.ok().put("data",zoomMeeting);
            } else {
                return R.error("获取会议室失败");
            }
        } catch (MyException e) {
            return R.error(e.getMsg());
        }
    }

    /**
     * 通过zoomid获取会议室
     *
     * @param zoomid 会议id
     * @throws MyException
     */
    @Login
    @PostMapping("getMeetByZoomid")
    @ApiOperation("通过zoomid获取会议室")
    public R getMeetByZoomid(@RequestParam(value = "zoomid", required = true) String zoomid) {
        try {
            HyZoomMeeting zoomMeeting = meetingService.getOne(new QueryWrapper<HyZoomMeeting>().eq("zoomId", zoomid));
            if (zoomMeeting != null) {
                return R.ok().put("data",zoomMeeting);
            } else {
                return R.error("您来晚了，会议已经结束");
            }
        } catch (MyException e) {
            return R.error(e.getMsg());
        }
    }


    /**
     * 通过会议室拥有者uid获取会议室
     *
     * @param uid 用户uid
     * @throws MyException
     */
    @Login
    @PostMapping("getMeetByUid")
//    @ApiOperation("通过会议室拥有者uid获取会议室")
    public R getMeetByUid(@RequestParam(value = "uid", required = true) Integer uid) {
        try {
            Map<String, Object> params = new HashMap<>();
            // 获取是否有专属会议室
            params.put("orderByField", "endAt");
            params.put("isAsc", false);
            params.put("ouid", uid.intValue());
            params.put("showstatus", FrogConstant.BasicStatus.TRUE.getValue());
            // 要关联查询专属名称、参会标记、所属账号【手机号】、附加账号数量、创建时间，启用时间、到期时间、
            Page page = meetingService.selectZoomMeeting(new QueryExt(params));

            if (page.getRecords().size() > 0) {
                // 检查登录设备是否超过三台
                List<HyLoginInfo> infoList = infoService.list(new QueryWrapper<HyLoginInfo>().eq("uid", uid).eq("status", 1));
                if (infoList.size() > 3) {
                    return R.error("当前登录设备超过三台，请联系飞鸽视讯客服处理");
                }
                // 放入关联账号列表结合
                List<HyZoomMeeting> list = page.getRecords();
                for (int i = 0; i < list.size(); i++) {
                    List<String> phoneList = new ArrayList<>();
                    //如果当前用户uid是主账号,可续费
                    if (uid == list.get(i).getUid().intValue()) {
                        list.get(i).setIsAffiliated(1);
                    } else {
                        list.get(i).setIsAffiliated(0);
                    }
                    // 判断是否到期
                    if (list.get(i).getEndat().getTime() > System.currentTimeMillis()) {
                        list.get(i).setIsExpire(0);
                    } else {
                        list.get(i).setIsExpire(1);
                    }
                    List<HyZoomVipUserEntity> result = zoomVipUserService.list(
                            new QueryWrapper<HyZoomVipUserEntity>().eq("zid", list.get(i).getId()).eq("statu", FrogConstant.BasicStatus.TRUE.getValue()));
                    if (result.size() > 0) {
                        for (int j = 0; j < result.size(); j++) {
                            String phone;
                            if (result.get(j).getOuid().longValue() != list.get(i).getUid().longValue()) {
                                phone = frogUserService.getOne(new QueryWrapper<User>().eq("uid", result.get(j).getOuid())).getPhone();
                                phoneList.add(phone);
                            }
                        }
                    }
                    list.get(i).setList(phoneList);
                }
            }
            return R.ok().put("data", page);
        } catch (MyException e) {
            return R.error(e.getMsg());
        }
    }

    /**
     * 通过会议室唯一标记获取会议室
     *
     * @param zoomtab 专属会议室标记
     * @throws MyException
     */
    @Login
    @PostMapping("getMeetByZoomtab")
    @ApiOperation("通过会议室唯一标记获取会议室")
    public R getMeetByZoomtab(@RequestParam(value = "zoomtab", required = true) String zoomtab) {
        try {
            HyZoomMeeting zoomMeeting = meetingService.getOne(new QueryWrapper<HyZoomMeeting>().eq("zoomTab", zoomtab));
            if (zoomMeeting != null) {
                return R.ok().put("data",zoomMeeting);
            } else {
                return R.error("请输入正确的参会ID");
            }
        } catch (MyException e) {
            return R.error(e.getMsg());
        }
    }

    /**
     * 获取免费体验会议室列表
     *
     * @param
     * @throws MyException
     */
    @ApiOperation("获取免费体验会议室列表")
    @PostMapping("getFreeMeetList")
    public @ResponseBody
    R getFreeMeetList() {
        Map<String, Object> params = new HashMap<>();
        params.put("orderByField", "id");
        params.put("isAsc", false);
        params.put("isvipzoom", FrogConstant.ZoomMeetType.FREE);
        params.put("showStatus", FrogConstant.BasicStatus.TRUE.getValue());
        Page page = meetingService.selectPageByConditions(new QueryExt<>(params));
        return R.ok().put("data", page);
    }


    /**
     * 获取公共会议室规模及外层列表
     *
     * @param
     * @throws MyException
     */
    @GetMapping("/getOutList")
    @ApiOperation("获取公共会议室规模及外层列表")
    public R getAllOutList() {
        // 获取所有公共会议室规模
        List<HyZoomMeeting> list = meetingService.list(new QueryWrapper<HyZoomMeeting>().eq("isVipZoom", FrogConstant.ZoomMeetType.COMMEN));
        // 定义list
        List<Integer> listAllType = new ArrayList<>();
        if (list.size() > 0) {
            for (HyZoomMeeting zoomMeeting : list) {
                // list遍历添加
                if (!listAllType.contains(zoomMeeting.getMeetingcapacity())) {
                    listAllType.add(zoomMeeting.getMeetingcapacity());
                }
            }
            List<OutMeetVo> listOmeet = new ArrayList<>();
            // 循环遍历出所有会议方数
            for (Integer capacity : listAllType) {
                OutMeetVo outMeet = new OutMeetVo();
                outMeet.setCapacity(capacity);
                List<HyZoomMeeting> listZoom = meetingService.list(new QueryWrapper<HyZoomMeeting>().eq(
                        "isVipZoom", FrogConstant.ZoomMeetType.COMMEN).eq("meetingCapacity", capacity));
                // 遍历每种方数会议室集合
                for (HyZoomMeeting metting : listZoom) {
                    // 如果已被预约,不管是不是空闲,直接计入预约中,这样才不会影响总数
                    if (metting.getReserveUid() != null) {
                        outMeet.setReserve(outMeet.getReserve() + 1);
                        continue;
                    }
                    // 如果为空闲,空闲会议室+1
                    if (metting.getMeetstatus() == 0) {
                        outMeet.setFree(outMeet.getFree() + 1);
                    }
                    // 如果使用中,使用中会议室+1
                    if (metting.getMeetstatus() == 1) {
                        outMeet.setUse(outMeet.getUse() + 1);
                    }
                }
                // 每种方数所有会议室遍历结束,统筹放入集合内
                listOmeet.add(outMeet);
            }
            return R.ok().put("data", listOmeet);
        } else {
            return R.error("不存在任何会议室");
        }
    }


    /**
     * 通过会议室方数获取会议室
     *
     * @param
     * @throws MyException
     */
    @PostMapping("/getPublicMeetList")
    @ApiOperation("通过会议室方数获取会议室")
    public R getNewPublicMeetList(@RequestParam(required = true, value = "meetingcapacity") Integer meetingcapacity) {
        List<HyZoomMeeting> listZoom = meetingService.list(new QueryWrapper<HyZoomMeeting>().eq(
                "isVipZoom", FrogConstant.ZoomMeetType.COMMEN).eq("meetingCapacity", meetingcapacity));
        // 循环截取时间
        SimpleDateFormat sdfa = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        if (listZoom.size() > 0) {
            for (int i = 0; i < listZoom.size(); i++) {
                if (listZoom.get(i).getUpdateat() != null) {
                    String sDate = sdfa.format(listZoom.get(i).getUpdateat());
                    listZoom.get(i).setEnd(sDate);
                }
            }
            return R.ok().put("data", listZoom);
        } else {
            return R.error("参数传递错误,无此类会议室");
        }

    }

    /**
     * 客户端正式开会
     *
     * @param form
     * @throws MyException
     */
    @Login
    @PostMapping("/openMeeting")
    @ApiOperation("客户端正式开会")
    public R openNewMeeting(@RequestBody OpenMeetForm form) throws MyException {
        try {
            ValidatorUtils.validateEntity(form);
            HyZoomMeeting meeting = meetingService.getById(form.getId());
            BeanUtils.copyProperties(form, meeting);
            if (meeting.getShowstatus() != 1) {
                return R.error("该会议室被禁用");
            }
            // 专属可能
            if (meeting.getEndat() != null && meeting.getEndat().getTime() < System.currentTimeMillis()) {
                return R.error("会议室已到期");
            }
            if (meeting.getReserveUid() != null) {
                if (!meeting.getReserveUid().equals(form.getCurrentuid().toString())) {
                    return R.error("该会议室已被其他用户预约,建议升级app版本.");
                }
            }
            // 如果是体验会议室,持续时间必传
            if (meeting.getIsvipzoom() == 0 && form.getTime() == null) {
                return R.error("会议持续时间必传");
            }
            if (meeting.getMeetstatus() != 0) {
                return R.error("会议室已被抢占,别沮丧换个会议室。");
            }
            // 收费逻辑
            if (meeting.getIsvipzoom() == 0) {
                this.costMoneyOpen(meeting);
            }
            // 使用体验时,每个人每天只能使用体验两次
            if (meeting.getIsvipzoom() == 2) {
                List<HyZoomHistory> list = historyService.list(new QueryWrapper<HyZoomHistory>().eq(
                        "hostId",form.getCurrentuid()).eq("mtype",FrogConstant.ZoomMeetType.FREE)
                .eq("dateCount",DateUtils.format(new Date(), DateUtils.DATE_PATTERN)));
                if (list.size() >= 3) {
                    return R.error("您当天使用免费体验会议室次数超限");
                }
            }
            meeting.setHymeetid(String.valueOf(System.currentTimeMillis()));
            if (form.getPassword() != null) {
                meeting.setPassword(form.getPassword());
            }
            HyZoomMeeting newMetting = meetingService.openMeetZoom(meeting);
            if (newMetting != null) {
                return R.ok().put("data", newMetting);
            } else {
                meeting.setMeetstatus(0);
                meetingService.updateById(meeting);
                return R.error("服务端开会失败");
            }
        } catch (MyException e) {
            return R.error(e.getMessage());
        }
    }


    /**
     * 提交会议反馈
     *
     * @param zoomId
     * @param message
     * @throws MyException
     */
    @Login
    @PostMapping("/create/zoomFeedback")
    @ApiOperation("创建会议反馈")
    public R deleteCurrentMeet(@RequestParam(value = "zoomId", required = true) Integer zoomId,
                               @RequestParam(value = "message", required = true) String message,
                               @RequestParam(value = "uid", required = true) Integer uid) {
        try {
            // 查询对应用户
            User frogUserEntity = frogUserService.getById(uid);
            if (frogUserEntity == null) {
                return R.error("对象uid错误");
            }
            // 查询出会议对象
            HyZoomHistory zoomHistory = historyService.getOne(new QueryWrapper<HyZoomHistory>().eq("true_meet_id", zoomId));
            if (zoomHistory == null) {
                return R.error("会议id错误");
            }
            // 防会议重复反馈
            HyZoomFeedbackEntity hyZoomFeedbackEntity = zoomFeedbackService.getOne(new QueryWrapper<HyZoomFeedbackEntity>().eq("zoom_id", zoomId).eq("uid", uid));
            if (hyZoomFeedbackEntity != null) {
                return R.error("同一用户对同场会议只能反馈一次");
            }
            HyZoomFeedbackEntity hyZoomFeedback = new HyZoomFeedbackEntity();
            hyZoomFeedback.setZoomId(zoomId);
            hyZoomFeedback.setCreateTime(new Date());
            hyZoomFeedback.setPhone(frogUserEntity.getPhone());
            hyZoomFeedback.setUid(uid);
            hyZoomFeedback.setMessage(message);

            Boolean result = zoomFeedbackService.save(hyZoomFeedback);
            if (result) {
                return R.ok("提交成功");
            } else {
                return R.error("提交失败");
            }
        } catch (MyException e) {
            return R.error(e.getMsg());
        }
    }

    /**
     * 接收集合发送短信及推送
     *
     * @param phoneStr
     * @throws MyException
     */
    /*@Login*/
    @PostMapping("inviteUserList")
    @ApiOperation("接收集合发送短信及推送")
    public R inviteUserList(@RequestParam(value = "list", required = true) String phoneStr,
                            @RequestParam(value = "id", required = true) Integer id,
                            @RequestParam(value = "uid", required = true) Long uid) throws Exception {
        try {
            UMENG_LOG.info("phoneStr:" + phoneStr);
            JSONArray jsonArray = JSON.parseArray(phoneStr);
            if (jsonArray.size() <= 0) {
                return R.error("集合长度为空,无需发送");
            } else {
                HyZoomMeeting zoomMeeting = meetingService.getOne(new QueryWrapper<HyZoomMeeting>().eq("zoomId", id));
                User user;
                HyAppPushEntity appPushEntity = new HyAppPushEntity();
                appPushEntity.setTitle("参会通知");
                appPushEntity.setText("您的视频会议即将开始，立即加入");
                appPushEntity.setTicker(" ");

                //设置即时
                appPushEntity.setType(0);
                appPushEntity.setStartTime(new Date());
                //设置推送渠道所有
                appPushEntity.setDisplayChannel(0);
                appPushEntity.setSid(id);
                appPushEntity.setUid(uid);
                //设置全部推送
                appPushEntity.setDisplayRange(1);
                //设置消息类型为参会提醒
                appPushEntity.setAppMessageType(4);
                //设置推送对象为go_custom，用户自定义
                appPushEntity.setAfterOpen(1);
                //设置推送模块为go_zoom
                appPushEntity.setCustomAfterOpen(FrogConstant.CustomAfterOpen.go_zoom.getValue());

                for (int i = 0; i < jsonArray.size(); i++) {
                    // 检索是不是在用户库中
                    user = frogUserService.getOne(new QueryWrapper<User>().eq("phone", jsonArray.get(i)));
                    //如果用户不存在或者用户的token不存在
                    if (user == null || redisUtils.getMap(FrogConstant.RedisKey.DEVICE_TOKEN).get(user.getUid().toString()) == null) {
                        // 发短信
                        if (zoomMeeting.getZoomtab() == null) {
                            zoomMeeting.setZoomtab("");
                        }
                        if (StringUtils.isMobile(jsonArray.getString(i))) {
                            frogUserService.sendSmsByMeetInvite(jsonArray.getString(i), zoomMeeting.getZoomtab());
                        }
                    } else {
                        // 发推送
                        appPushEntity.setPhone(user.getPhone());
                        umengService.sendSingleBroadcast(appPushEntity);
                    }
                }

                return R.ok();
            }
        } catch (MyException e) {
            return R.error(e.getMsg());
        }
    }

    /**
     * 会议结束获取会议历史信息
     *
     * @param
     */
    @Login
    @GetMapping("/getEndHistory")
    @ApiOperation("会议结束获取会议历史信息")
    public R getEndHistory(@RequestParam(value = "zoomId", required = true) Integer zoomId) {
        HyZoomHistory history = historyService.getOne(new QueryWrapper<HyZoomHistory>().eq("true_meet_id", zoomId));
        if (history != null) {
            HyMeetHistoryVo vo = new HyMeetHistoryVo();
            vo.setTopic(history.getTopic());
            // 把开会者切割只计算参会者人数
            String[] numstr = history.getJoinId().split(";");
            vo.setJoinNum(numstr.length - 1);
            if (history.getEndDate() != null) {
                // 计算持续时长
                long dis = history.getEndDate().getTime() - history.getCreateDate().getTime();
                long disSecond = dis / 1000;
                // 如果体验并且大于等于十分钟。
                // 小于一分钟。 --- 刚刚
                if (disSecond < 60) {
                    vo.setLastTime("共持续0时0分" + disSecond + "秒");
                }
                // 一分钟以上60分钟内
                if (disSecond > 60 && disSecond < 3600) {
                    vo.setLastTime("共持续0时" + disSecond / 60 + "分" + disSecond % 60 + "秒");
                }
                // 一小时以上24小时内
                if (disSecond >= 3600 && disSecond < 86400) {
                    vo.setLastTime("共持续" + disSecond / 3600 + "时" + (disSecond % 3600) / 60 + "分钟" + ((disSecond % 3600)) % 60 + "秒");
                }
                if (disSecond >= 86400) {
                    vo.setLastTime("超过一天");
                }
                if (history.getMtype() == 2 && disSecond >= 600) {
                    vo.setLastTime("共持续0时10分0秒");
                }
                return R.ok().put("Object", vo);
            } else {
                return R.error("回调尚未结束");
            }

        } else {
            return R.error("查询错误");
        }
    }

    /**
     * 获取需付费多少接口
     *
     * @param
     */
    @Login
    @GetMapping("/getJoinNeedpay")
    @ApiOperation("获取需付费多少接口")
    public R getJoinNeedpay(@RequestParam(value = "id", required = true) Integer id,
                            @ApiIgnore @RequestAttribute(value = "userId") Long uid) {
        try {
            HyZoomMeeting hyZoomMeeting = meetingService.getById(id);
            int pay = meetingService.getJoinBasicMeetNeedpay(hyZoomMeeting);
            if(hyZoomMeeting.getPrice() != null){
                return R.ok().put("data", pay + hyZoomMeeting.getPrice());
            }else{
                return R.ok().put("data", pay);
            }
        } catch (MyException e) {
            return R.error(e.getMsg());
        }
    }

    /**
     * 获取所有开会时长对象列表
     *
     * @param isVipZoom
     * @throws MyException
     */
    @Login
    @GetMapping("/getMeetTimeList")
    @ApiOperation("获取所有开会时长对象列表")
    public R getMeetTimeList(@RequestParam(value = "isVipZoom", required = true) Integer isVipZoom) {
        try {
            List<HyZotConfig> list = hyZotConfigService.list(new QueryWrapper<HyZotConfig>().eq("type", isVipZoom));
            if (list != null) {
                return R.ok().put("data", list);
            } else {
                return R.error("开会时长配置未生效");
            }
        } catch (MyException e) {
            return R.error(e.getMessage());
        }
    }


    public void costMoneyOpen(HyZoomMeeting metting) throws MyException {
        // 根据客户端回传的扣费金额开始扣费
        int needPay = 0;
        if (metting.getIsvipzoom() == 0 && metting.getTime() != null) {
            needPay = meetingService.getNeedpay(metting);
        } else {
            throw new MyException("无此开会方式系统收费配置");
        }
        // 先检查该用户该规格是否拥有特权卡。特权卡是否超过有效期
        HyPowerUser powerUser = powerUserService.getOne(new QueryWrapper<HyPowerUser>().eq(
                "uid", metting.getCurrentuid()).eq(
                "capacity", metting.getMeetingcapacity()
        ));
        if (powerUser != null && powerUser.getEnddate().getTime() > System.currentTimeMillis()) {
            // 拥有权益并且有效
            System.out.println("拥有此方数开会特权卡,有效期---" + powerUser.getEnddate());
        } else {
            userService.reduce(metting.getCurrentuid(), needPay);
            // 生成订单,用户支付给无锡汉咏
            HyPayRecord payRecord = new HyPayRecord();
            payRecord.setCreatedate(new Date());
            payRecord.setTotal(needPay);
            payRecord.setMoney(0);
            payRecord.setNum(0);
            payRecord.setType(PayType.open_meet_pay.getCode());
            payRecord.setYid(FrogConstant.admin_uid);
            // 扣费者id
            payRecord.setUid(metting.getCurrentuid());
            // 资源对应id(本次为抽取无资源)
            payRecord.setSid(metting.getId());
            payRecordService.save(payRecord);
        }

    }


}
